package com.quyunshuo.module.home.fragment.collection

import android.os.Build.VERSION_CODES.P
import android.util.Log
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.quyunshuo.androidbaseframemvvm.base.mvvm.vm.BaseViewModel
import com.quyunshuo.androidbaseframemvvm.base.utils.status.ViewStatusHelper
import com.quyunshuo.androidbaseframemvvm.network.bean.ArticleListRes2
import com.quyunshuo.module.home.fragment.CallErrors
import com.quyunshuo.module.home.fragment.HomeState
import com.quyunshuo.module.home.fragment.Result
import com.quyunshuo.module.home.fragment.reduce
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.retryWhen
import kotlinx.coroutines.launch
import java.io.IOException
import javax.inject.Inject

/**
 * @author DBoy 2021/7/6 <p>
 * - 文件描述 : ViewModel再ViewPager2的Fragment中会随着Fragment执行[Fragment.onDestory]一同销毁。
 * 所以一些需要长期保存的变量数据，不适合保存再ViewModel，考虑使用[ViewStatusHelper]保存页面上部分数据，
 * 页面恢复的时候再交给ViewModel处理,例如[recreatedCont]
 */
@HiltViewModel
class CollectionViewModel @Inject constructor() :
    BaseViewModel() {

    @Inject
    lateinit var repository: CollectionRepository

    /**
     * 首个数据
     */
    val firstData1 = MutableLiveData<HomeState>()
    val firstData2 = MutableLiveData<Result<ArticleListRes2>>()

    /**
     * 获取数据
     */
    fun getData(page :Int) {
        viewModelScope.launch(Dispatchers.IO) {
            repository.getData(page)
                .retryWhen { cause, attempt ->
                    Log.d("retryWhen0", "getData: $cause $attempt")
                    if (cause is IOException && attempt<3) {
                        Log.d("retryWhen1", "getData: $cause")
                        delay(500)
                        true
                    }else{
                        Log.d("retryWhen2", "getData: $cause")
                        false
                    }

                }
                .catch {
                    Log.d("retryWhen2 DJC", "getData: ")
                    firstData2.postValue(Result.Error(CallErrors.ErrorException(it)))
                }
                .onStart {
                    changeStateView(loading = true)
                    firstData2.postValue(Result.Loading)
                }
                .collect {
                    changeStateView(hide = true)
                    if (it.data==null) {
                        firstData2.postValue(Result.Error(CallErrors.ErrorEmptyData))
                    }else{
                        firstData2.postValue(Result.Success(it.data))
                    }
                }
        }
    }

    /**
     * 获取数据
     */
    fun getData1(page :Int) {
        viewModelScope.launch(Dispatchers.IO) {
            repository.getData1(page)
                .retryWhen { cause, attempt ->
                    Log.d("retryWhen0", "getData: $cause $attempt")
                    if (cause is IOException && attempt<3) {
                        Log.d("retryWhen1", "getData: $cause")
                        delay(500)
                        true
                    }else{
                        Log.d("retryWhen2", "getData: $cause")
                        false
                    }

                }
                .catch {
                    Log.d("retryWhen2 DJC", "getData: ")
                    firstData1.postValue(Result.Error(CallErrors.ErrorException(it)).reduce())
                }
                .onStart {
                    changeStateView(loading = true)
                    firstData1.postValue(Result.Loading.reduce())
                }
                .collect {
                    changeStateView(hide = true)
                    when(it){
                        is Result.Success->{
                            firstData1.postValue(it.reduce())
                        }
                        is Result.Error->{
                            firstData1.postValue(it.reduce())
                        }
                        Result.Loading -> {
                        }
                    }
                }
        }
    }

    fun dispatchIntent(intent: CollectionIntent) {
        when(intent){
            is CollectionIntent.SearchCollections->{
                getData(intent.page)
            }
            is CollectionIntent.LoadAllCollections->{

            }
        }
    }

}
